package org.easyupdater;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.log4j.Logger;
import org.easyupdater.model.BundleSpec;

public class DownloadManager implements IDownloadManager {

	private static final Logger log = Logger.getLogger(DownloadManager.class);
	private File downloadDirectory;

	/**
	 * Download the bundle from its remote repository
	 * 
	 * @return boolean value indicating whether the download was successful
	 */
	public boolean downloadBundle(String applicationUpdateSiteURL, BundleSpec bundleSpec) {
		String fullBundleURL = null;
		String bundleRelativeUrl = bundleSpec.getUrl();
		fullBundleURL = applicationUpdateSiteURL;
		if (bundleRelativeUrl.charAt(bundleRelativeUrl.length() - 1) != '/') {
			fullBundleURL += '/';
		}
		fullBundleURL += bundleRelativeUrl;

		try {
			URL url = new URL(fullBundleURL);
			URLConnection urlConnection = url.openConnection();
			InputStream is = urlConnection.getInputStream();
			String bundleFullName = bundleSpec.getId() + "-" + bundleSpec.getVersion() + ".jar";
			File tempOut = new File(downloadDirectory, bundleFullName + ".part");
			boolean creationSuccessful = tempOut.createNewFile();
			if (!creationSuccessful) {
				log.error("Could not create new file on the disk: " + tempOut.getAbsolutePath());
				return false;
			}
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempOut));
			int read;
			byte[] buffer = new byte[1024];
			while ((read = is.read(buffer)) != -1) {
				bos.write(buffer, 0, read);
			}
			bos.flush();
			bos.close();
			is.close();
			File bundleJar = new File(downloadDirectory, bundleFullName);
			boolean renameSuccessful = tempOut.renameTo(bundleJar);
			if (!renameSuccessful) {
				log.error("Could not rename file: " + tempOut.getAbsolutePath());
				return false;
			}
			bundleSpec.setLocalJar(bundleJar);
		} catch (MalformedURLException e) {
			log.error("Invalid bundle URL: " + fullBundleURL, e);
			return false;
		} catch (IOException e) {
			log.error("Could not download bundle from URL: " + fullBundleURL, e);
			return false;
		}
		return true;
	}

	public File getDownloadDirectory() {
		return downloadDirectory;
	}

	public void setDownloadDirectory(File downloadDirectory) {
		this.downloadDirectory = downloadDirectory;
	}

}
